import type {WsEvent} from "./WsEvent";
import type {WebSocketWrapper} from "../framework/WebsocketWrapper.ts";

export class EventListener {
    private readonly channel: string
    private readonly handler: (d: any)=>void
    constructor(channel: string, handler: (d: any)=>void) {
        this.channel = channel
        this.handler = handler
    }
    getChannel(): string {
        return this.channel
    }
    getHandler(): (d: any)=>void {
        return this.handler
    }
}
class BaseHandler {
    defaultListener: EventListener
    listeners: Map<string, EventListener>
    constructor() {
        this.listeners = new Map<string, EventListener>()
    }
    getListener(channel: string): EventListener {
        let listener = this.listeners.get(channel)
        if (!listener) {
            return this.defaultListener
        }
        return listener
    }
    bindDefaultListener(listener: EventListener): void {
        this.defaultListener = listener
    }
    bindEvents(listener: EventListener): void {
        this.listeners.set(listener.getChannel(),listener)
    }
}

class ApiHandler extends BaseHandler {
    onData(event: WsEvent): void {
        let listener = this.getListener(event.channel)
        if (!listener) {
            return
        }
        listener.getHandler()(event.payload)
    }
}
class MqHandler extends BaseHandler{
    onData(event: WsEvent): void {
        let listener = this.getListener(event.channel)
        if (!listener) {
            return
        }
        let h = listener.getHandler()
        if (!h) {
            return
        }
        h(event.payload)
    }
}

export class Stream {
    ws: WebSocketWrapper
    apiHandler: ApiHandler
    mqHandler: MqHandler
    enableDefaultHandler: boolean = false
    constructor(ws: WebSocketWrapper) {
        this.ws = ws
        this.mqHandler = new MqHandler()
        this.apiHandler = new ApiHandler()
        this.ws.setListener((event: any) => {
            this.onData(event)
        })
        if (this.enableDefaultHandler) {
            this.mqHandler.bindDefaultListener(new EventListener(
                "",
                (d: any) => {
                console.log(d)
            }))
        }
    }

    private onData(event: any):void {
        try {
            let evt = event as WsEvent
            if (evt.category == 'mq') {
                this.mqHandler.onData(evt)
            } else if (evt.category == 'api') {
                this.apiHandler.onData(evt)
            } else {
                console.log('unknown ws event')
                console.log(event)
            }
        } catch (e) {
            console.log(e)
            console.log(event)
        }
    }
}